#+AUTHOR:Joshua Branson
#+TITLE: Easy Simpliying Fractions
#+LATEX_HEADER: \usepackage{lmodern}
#+LATEX_HEADER: \usepackage[QX]{fontenc}
#+OPTIONS: H:10 toc:nil

* Easy Simpliying Fractions
:PROPERTIES:
:ID:       23e8229d-54fe-441f-a225-5b9d1d48b5cc
:END:

Input:

4 8
1536 78360
51478 5536
46410 119340
7673 4729
4096 1024


Output:

1 2
64 3265
25739 2768
7 18
7673 4729
4 1

The main arguments is a list that looks like:
./277.scheme 3 7 15 25 10 14

So I have to ignore (car args).
#+BEGIN_SRC scheme :tangle yes
  #!/home/joshua/.guix-profile/bin/guile \
  -e main -s
  !#

  (define (main args)
    ;;(display (get-type args))
    (let loop ((args args))
      (unless (null? (cdr args))
        (let ((num (string->number (car (cdr args))))
              (den (string->number (car (cdr (cdr args))))))
          ;; (display (car (cdr args)))
          ;; (display " ")
          ;; (display (car (cdr (cdr args))))
          ;; (display "\n")
          (simplyify num den)
          (loop (cdr (cdr args)))))))
#+END_SRC

The function that takes a fraction and spits out its simplified version.
#+BEGIN_SRC scheme :tangle yes
    (define (simplyify num den)
      (let loop ((factor (commonFactor num den)))
        (if (number? factor)
            (begin
              (set! num (/ num factor))
              (set! den (/ den factor))
              (loop (commonFactor num den)))
            ;;(cons num (cons den '()))
            (begin
              (display num)
              (display " ")
              (display den)
              (display "\n")))))
#+END_SRC

Function that will determine if a numbers are prime.  #t if prime;  Other will return the smallest common factor of both.
I could modify this to return all of their factors...But that is kind of hard...How do you know when you're found the last common factor?
The cons need to be build like this:  (cons 2 (cons 3 (cons 4 (cons 5 (cons 6 '())))))
Suppose that you get to the point in the loop where you find 6.  If you knew that 6 was the last prime, then you could do a (cons 6 '())
BUT if you don't then you will loop again at 7, 8, etc.  Finally you will discover that 6 was the last factor.  So you'd have to do (cons 6 (cons '() '())), which is not terrible, but your list looks like '(1 3 4 5 6 '())

#+BEGIN_SRC scheme :tangle yes
  (define (commonFactor a b)
    ;;the named loop defined a closure.  It's essentially naming a function called loop, and calling it repeatily
    (let loop ((factor 2))
      ;; if facter is half of the number, then return #f
      (cond ((= factor (1+ (ceiling (/ a 2))))
             ;; if factor is half of a, then a is prime.
             ;; test to see if a is a factor of b, and a != b
             ;; Also a != 1... I feel like this is not very mathematical
             (if (and (not (= a b)) (= 0 (modulo b a)) (not (= a 1)))
                 a
                 #f))
            ((= 0 (modulo a factor) (modulo b factor))
             factor)
            ;;if factor does not evenly divide a and b, then start the loop again
            (else (loop (1+ factor))))))
#+END_SRC

** Some notes
I was trying to make commonFactor spit out a list of all the commonFactors of two numbers...BUT It's hard to recursively define a function that spits out a list of all of the common factors...
#+BEGIN_SRC scheme
  (let loop ((x 1))
    (if (< x 5)
        (cons x (loop (1+ x)))
        (cons x '())))
#+END_SRC

Really bad to print out 1-3.
#+BEGIN_SRC scheme
  (define (1-3)
    (define ((x 1))
      (if (< x 4)
          (begin
            (display x)
            (display " ")
            (set! x (+ x 1))
            (1-3)))))

#+END_SRC

Easy/hard code to print out 1-3
#+BEGIN_SRC scheme
  (define (1-3)
    (define (inner x)
      (when (< x 4)
        (display x)
        (display " ")
        (inner (1+ x))))
    (inner 1))
#+END_SRC

Named let to print out 1-3
#+BEGIN_SRC scheme
  (define (1-3)
    (let loop ((x 1))
      (when (< x 4)
        (display x)
        (display " ")
        (loop (1+ x)))))
#+END_SRC

#+BEGIN_SRC scheme
  (define (make-serial-number-generator)
    (let ((current-serial-number 0))
      (lambda ()
        (set! current-serial-number (+ current-serial-number 1))
        current-serial-number)))

  (define entry-sn-generator (make-serial-number-generator))

  (entry-sn-generator)
#+END_SRC
